/*
*	Copyright (C) 2014  Julio Montes, Mario Carrillo
*	
*	Julio Montes e-mail: imc.coder@gmail.com 
*
*	Mario Carrillo e-mail: mario_90ago@live.com.mx
*
*	BSD 3-Clause License
*/

#include "sdk/include/editor.h"

#include "sdk/include/lexer.h"
#include "sdk/include/cfgmgr.h"
#include "sdk/include/path.h"

namespace sdk
{
    BEGIN_EVENT_TABLE( Editor, wxScintilla )
        EVT_SCI_UPDATEUI( wxID_ANY, Editor::OnUpdateUI )
        EVT_SCI_MARGINCLICK( wxID_ANY, Editor::OnMarginClick )
        EVT_SCI_CHARADDED( wxID_ANY, Editor::OnCharAddeed )
        EVT_KILL_FOCUS( Editor::OnKillFocus )
    END_EVENT_TABLE()

    const wxString Editor::s_fileConfig = sdk::Path::s_dirConfig + wxT( "settings_editor.xml" );


    const wxString Editor::FontEncodingString[]={
    wxT( "SYSTEM" ), wxT( "DEFAULT" ), wxT( "ISO8859_1" ), wxT( "ISO8859_2" ),
    wxT( "ISO8859_3" ), wxT( "ISO8859_4" ), wxT( "ISO8859_5" ), wxT( "ISO8859_6" ),
    wxT( "ISO8859_7" ), wxT( "ISO8859_8" ), wxT( "ISO8859_9" ), wxT( "ISO8859_10" ),
    wxT( "ISO8859_11" ), wxT( "ISO8859_12" ), wxT( "ISO8859_13" ), wxT( "ISO8859_14" ),
    wxT( "ISO8859_15" ), wxT( "ISO8859_MAX" ), wxT( "KOI8" ), wxT( "KOI8_U" ),
    wxT( "ALTERNATIVE" ), wxT( "BULGARIAN" ), wxT( "CP437" ), wxT( "CP850" ),
    wxT( "CP852" ), wxT( "CP855" ), wxT( "CP866" ), wxT( "CP874" ), wxT( "CP932" ),
    wxT( "CP936" ), wxT( "CP949" ), wxT( "CP950" ), wxT( "CP1250" ), wxT( "CP1251" ),
    wxT( "CP1252" ), wxT( "CP1253" ), wxT( "CP1254" ), wxT( "CP1255" ), wxT( "CP1256" ),
    wxT( "CP1257" ), wxT( "CP12_MAX" ), wxT( "UTF-7" ), wxT( "UTF-8" ), wxT( "EUC_JP" ),
    wxT( "UTF16BE" ), wxT( "UTF16LE" ), wxT( "UTF32BE" ), wxT( "UTF32LE" ), wxT( "MACROMAN" ),
    wxT( "MACJAPANESE" ), wxT( "MACCHINESETRAD" ), wxT( "MACKOREAN" ), wxT( "MACARABIC" ),
    wxT( "MACHEBREW" ), wxT( "MACGREEK" ), wxT( "MACCYRILLIC" ), wxT( "MACDEVANAGARI" ),
    wxT( "MACGURMUKHI" ), wxT( "MACGUJARATI" ), wxT( "MACORIYA" ), wxT( "MACBENGALI" ),
    wxT( "MACTAMIL" ), wxT( "MACTELUGU" ), wxT( "MACKANNADA" ), wxT( "MACMALAJALAM" ),
    wxT( "MACSINHALESE" ), wxT( "MACBURMESE" ), wxT( "MACKHMER" ), wxT( "MACTHAI" ),
    wxT( "MACLAOTIAN" ), wxT( "MACGEORGIAN" ), wxT( "MACARMENIAN" ), wxT( "MACCHINESESIMP" ),
    wxT( "MACTIBETAN" ), wxT( "MACMONGOLIAN" ), wxT( "MACETHIOPIC" ), wxT( "MACCENTRALEUR" ),
    wxT( "MACVIATNAMESE" ), wxT( "MACARABICEXT" ), wxT( "MACSYMBOL" ), wxT( "MACDINGBATS" ),
    wxT( "MACTURKISH" ), wxT( "MACCROATIAN" ), wxT( "MACICELANDIC" ), wxT( "MACROMANIAN" ),
    wxT( "MACCELTIC" ), wxT( "MACGAELIC" ), wxT( "MACKEYBOARD" ), wxT( "ISO2022JP" )
    };

    const int MARGIN_LINE_NUMBERS = 0;
    const int MARGIN_FOLD = 3;

    Editor::Editor( wxWindow *parent, wxWindowID id )
        : wxScintilla( parent, id ), m_lexer( NULL )
    {
        SetVisiblePolicy( wxSCI_VISIBLE_STRICT | wxSCI_VISIBLE_SLOP, 1 );
        SetXCaretPolicy( wxSCI_CARET_EVEN | wxSCI_CARET_SLOP | wxSCI_VISIBLE_STRICT, 100 );
        SetYCaretPolicy( wxSCI_CARET_EVEN | wxSCI_CARET_SLOP | wxSCI_VISIBLE_STRICT, 1 );
        SetEOLMode( wxSCI_EOL_LF );//eol linux

        m_fileConfig = ConfigManager::Get()->GetFile( s_fileConfig );
    }

    Editor::~Editor()
    {

    }

    bool Editor::CanCopy() const
    {
        return GetSelectionEnd() != GetSelectionStart();
    }

    bool Editor::CanCut() const
    {
        return !GetReadOnly() && GetSelectionEnd() != GetSelectionStart();
    }

    /*bool Editor::CanPaste() const
    {
        return !GetReadOnly();
    }*/

//    bool Editor::CanAutoComplete() const
//    {
//        return !GetReadOnly() && m_lexer != NULL;
//    }

    void Editor::SetSelection( long posStart, long posEnd )
    {
        SetSelectionStart( posStart );
        SetSelectionEnd( posEnd );
    }

    void Editor::LoadFile( const wxString &fileName )
    {
        m_filename = fileName;
        wxScintilla::LoadFile( fileName );
        SetSavePoint();
        SetSelection( 0, 0 );
    }

	void Editor::SetFileName( const wxString &filename )
	{
		m_filename = filename;
	}

    const wxString &Editor::GetFileName() const
    {
        return m_filename;
    }

    const wxString &Editor::GetFontEncoding() const
    {
        return m_fontEncoding;
    }



    void Editor::SetLexer( const sdk::Lexer *lexer )
    {
        if( lexer != NULL )
        {
            StyleClearAll();
            ClearRegisteredImages();
            m_lexer = lexer;

            wxScintilla::SetLexer( m_lexer->GetIndex() );

            const int sizeFont = m_fileConfig->ReadInt( wxT( "/config/general/font/size" ), 10 );

            sdk::vectorStyles l_vectorStyles;
            m_lexer->GetStyles( &l_vectorStyles );
            for( size_t i=0; i<l_vectorStyles.size(); ++i )
            {
                const sdk::styleLexer *currentStyle = &l_vectorStyles[i];
                const int index = currentStyle->index;

                if( index >= 0 )
                {
                    StyleSetForeground( index, currentStyle->foreground );
                    StyleSetBackground( index, currentStyle->background );

                    wxFont l_font( sizeFont, wxFONTFAMILY_TELETYPE,
                        currentStyle->italic ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL,
                        currentStyle->bold ?  wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL,
                        currentStyle->underline,
                        m_fileConfig->ReadString( wxT( "/config/general/font/facename" ), wxT( "Monospace" ) ),
                        static_cast<wxFontEncoding>( m_fileConfig->ReadInt( wxT( "/config/other/encoding" ), 41 ) ) );

                    StyleSetFont( index, l_font );
                }
                else
                {
                    switch( index )
                    {
                        case -1:
                            SetSelBackground( true, currentStyle->background );
                        break;

                        case -2:
                            SetCaretLineBackground( currentStyle->background );
                        break;
                    }
                }

            }

            sdk::vectorWords l_vectorWords;
            m_lexer->GetKeywords( &l_vectorWords );
            for( size_t i=0; i<l_vectorWords.size(); ++i )
            {
                const sdk::keywordsLexer *currentKeywords = &l_vectorWords[i];
                SetKeyWords( currentKeywords->index, currentKeywords->keywords );
            }

            sdk::vectorImages l_vectorImages;
            m_lexer->GetImages( &l_vectorImages );
            for( size_t i=0; i<l_vectorImages.size(); ++i )
            {
                const sdk::imageLexer *currentImage = &l_vectorImages[i];
                if( wxFileExists( sdk::Path::s_dirLexers + currentImage->image ) )
                {
                    wxBitmap img;
                    if( img.LoadFile( sdk::Path::s_dirLexers + currentImage->image, wxBITMAP_TYPE_XPM ) )
                    {
                        LOGC( wxT( "Loading the image: " ) + sdk::Path::s_dirLexers + currentImage->image );
                        RegisterImage( currentImage->index, img );
                    }
                    else
                    {
                        //TODO: show message error
                    }
                }
            }
        }
    }

    void Editor::StripTrailingSpaces()
    {
        int maxLines = GetLineCount();
        for( int line = 0; line < maxLines; ++line )
        {
            int lineStart = PositionFromLine( line );
            int lineEnd = GetLineEndPosition( line );
            int i = lineEnd-1;
            wxChar ch = (wxChar)( GetCharAt( i ) );
            while( ( i >= lineStart ) && ( ( ch == wxT( ' ' ) ) || ( ch == wxT( '\t' ) ) ) )
            {
                --i;
                ch = (wxChar)( GetCharAt( i ) );
            }
            if( i < ( lineEnd-1 ) )
            {
                SetTargetStart( i+1 );
                SetTargetEnd( lineEnd );
                ReplaceTarget( wxT( "" ) );
            }
        }
    }

    void Editor::HighlightOccurrences()
    {
    // MAYBE FIX
    //    long startWord, endWord;
    //    GetSelection( &startWord, &endWord );
    //
    //    const int indicator = 10;
    //    SetIndicatorCurrent( indicator );
    //
    //    int lengthText = GetLength();
    //    if( startWord == endWord )
    //    {
    //        IndicatorClearRange( 0, lengthText );
    //        ///FIX: soluciona varios problemas como lo son: quitar los indicadores y la perdida de
    //        ///codigo cuando se pliega codigo y se le desplaza ese codigo  hacia abajo
    ////        Colourise( 0, lengthText );
    //        return;
    //    }
    //
    //    const wxString selectedText( GetTextRange( startWord, endWord ) );

        static long old_start;
        static long old_end;

        long startWord, endWord;
        GetSelection( &startWord, &endWord );

        if( old_start == startWord && old_end == endWord )
            return;

        old_start = startWord;
        old_end = endWord;

        const wxString selectedText( GetTextRange( startWord, endWord ) );

        const int lengthText = GetLength();

        const int indicator = 10;

        SetIndicatorCurrent( indicator );

        IndicatorClearRange( 0, lengthText );

        if( m_fileConfig->ReadBool( wxT( "/config/general/hilghtoccurrence/enabled" ), true )
                && selectedText.Length() > 2
                && selectedText.Find(_T(' ')) == wxNOT_FOUND
                && selectedText.Find(_T('\t')) == wxNOT_FOUND
                && selectedText.Find(_T('\n')) == wxNOT_FOUND )
        {

            IndicatorSetStyle( indicator, wxSCI_INDIC_HIGHLIGHT );
            //IndicatorSetAlpha( indicator, 100 );
            IndicatorSetForeground( indicator, m_fileConfig->ReadColour( wxT( "/config/general/hilghtoccurrence/colour" ), wxT( "#FF0000" ) ) );


            int flag = 0;
            if( m_fileConfig->ReadBool( wxT( "/config/general/hilghtoccurrence/casesensitive" ), true ) )
                flag |= wxSCI_FIND_MATCHCASE;

            if( m_fileConfig->ReadBool( wxT( "/config/general/hilghtoccurrence/wholeword" ), true ) )
                flag |= wxSCI_FIND_WHOLEWORD;

            //search algorithm and establishing indicators
            int lengthFound = selectedText.Len();
            for( int pos = FindText( 0, lengthText, selectedText, flag );
                pos != wxSCI_INVALID_POSITION ;
                pos = FindText( pos+=lengthFound, lengthText, selectedText, flag ) )
            {
                IndicatorFillRange( pos, lengthFound );
            }
        }
    }


    void Editor::HighlightBrace()
    {
        if( m_fileConfig->ReadBool( wxT( "/config/general/indentbrace/hilghtmatch" ), true ) )
        {
            const wxString strBrace = wxT( "(){}[]" );

            int c1 = GetCharAt( GetCurrentPos() );
            int c2 = GetCharAt( GetCurrentPos()-1 );

            if( strBrace.Find( ( wxChar )c1 ) != wxNOT_FOUND )
            {
                int match = BraceMatch( GetCurrentPos() );

                if( match != wxSCI_INVALID_POSITION )
                    BraceHighlight( GetCurrentPos(), match );

                else
                    BraceBadLight( GetCurrentPos() );

            }
            else if( strBrace.Find( ( wxChar ) c2 ) != wxNOT_FOUND )
            {
                int match = BraceMatch( GetCurrentPos()-1 );

                if( match != wxSCI_INVALID_POSITION )
                    BraceHighlight( GetCurrentPos()-1, match );

                else
                    BraceBadLight( GetCurrentPos()-1 );
            }
            else
                 BraceHighlight( -1, -1 );
        }
    }


    void Editor::AutoCompleteBrace( wxChar c )
    {
        const int currPos( GetCurrentPos() );

        switch( c )
        {
            case '(':
                AddText( wxT( ')' ) );
            break;

            case '[':
                AddText( wxT( ']' ) );
            break;

            case '{':
                AddText( wxT( '}' ) );
            break;

            default:
                SetTargetStart( currPos-1 );
                SetTargetEnd( currPos );
                ReplaceTarget( wxT( "" ) );
        }

        GotoPos( currPos );
    }

    void Editor::Autocomplete( bool key )
    {
        if( GetReadOnly() )
        {
            return;
        }

        if( m_lexer != NULL )
        {
            if( !AutoCompActive() || key )
            {
                const int currentPos = GetCurrentPos();
                const int startPos = WordStartPosition( currentPos, true );

                wxString l_words = m_lexer->GetWordsWith( GetTextRange( startPos, currentPos ) );
                if( !l_words.IsEmpty() )
                {
                    AutoCompShow( currentPos - startPos, l_words );
                }
            }
        }
    }






    void Editor::LoadSettings()
    {
        LoadAutoCompleteSettings();
        LoadFoldSettings();
        LoadOtherSettings();
        LoadGeneralSettings();
    }

    void Editor::LoadGeneralSettings()
    {
        /** Font Settings **/
        int italic = m_fileConfig->ReadBool( wxT( "/config/general/font/italic" ), false ) ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL;
        int bold = m_fileConfig->ReadBool( wxT( "/config/general/font/bold" ), false ) ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL;

        const int fencoding( m_fileConfig->ReadInt( wxT( "/config/other/encoding" ), 41 ) );
        m_fontEncoding = FontEncodingString[fencoding+1];
        wxFont font( m_fileConfig->ReadInt( wxT( "/config/general/font/size" ), 10 ) , wxFONTFAMILY_TELETYPE, italic,
                    bold, false, m_fileConfig->ReadString( wxT( "/config/general/font/facename" ), wxT( "Monospace" ) ),
                    static_cast<wxFontEncoding>( fencoding ) ) ;

        StyleSetFont( wxSCI_STYLE_DEFAULT, font );


        /** Tab Settings **/
        SetTabIndents( m_fileConfig->ReadBool( wxT( "/config/general/tab/tabindents" ), true ) );
        SetUseTabs( m_fileConfig->ReadBool( wxT( "/config/general/tab/usetabs" ), true ) );
        SetTabWidth( m_fileConfig->ReadInt( wxT( "/config/general/tab/tabsize" ), 4 ) );


        /** IndentSettings **/
        SetIndentationGuides( m_fileConfig->ReadBool( wxT( "/config/general/indentbrace/guides" ), false ) );
        SetBackSpaceUnIndents( m_fileConfig->ReadBool( wxT( "/config/general/indentbrace/backspaceunindent" ), false ) );


        /** Edge Settings **/
        SetEdgeMode( m_fileConfig->ReadInt( wxT( "/config/general/edge/line" ), 1 ) );
        SetEdgeColumn( m_fileConfig->ReadInt( wxT( "/config/general/edge/column" ), 80 ) );
        SetEdgeColour( m_fileConfig->ReadColour( wxT( "/config/general/edge/colour" ), wxT( "#E0E0E0" ) ) );


        /** EOF Settings **/
        SetViewEOL( m_fileConfig->ReadBool( wxT( "/config/general/eofoptions/showeolchars" ),false ) );


        /** Caret Settings **/
        SetCaretLineVisible( m_fileConfig->ReadBool( wxT( "/config/general/caretoptions/hilghtline" ), false ) );
        SetCaretLineBackground( m_fileConfig->ReadColour( wxT( "/config/general/caretoptions/hilghtlinecolour" ), wxT( "#FFFF00" ) ) );
        SetCaretPeriod( m_fileConfig->ReadInt( wxT( "/config/general/caretoptions/period" ), 500 ) );
        SetCaretWidth( m_fileConfig->ReadInt( wxT( "/config/general/caretoptions/width" ), 1 ) );
    }

    void Editor::LoadOtherSettings()
    {
        SetWrapMode( m_fileConfig->ReadInt( wxT( "/config/other/wordwrap" ), 0 ) );
        SetMarginType( MARGIN_LINE_NUMBERS, wxSCI_MARGIN_NUMBER );
        SetMarginWidth( MARGIN_LINE_NUMBERS, m_fileConfig->ReadBool( wxT( "/config/other/showln" ), true ) ? 40 : 0 );
        SetViewWhiteSpace( m_fileConfig->ReadInt( wxT( "/config/other/showspaces" ), 0 ) );
    }

    void Editor::LoadAutoCompleteSettings()
    {
        //AutoCompSetChooseSingle( true );

        AutoCompSetIgnoreCase( !m_fileConfig->ReadBool( wxT( "/config/codecompletion/sensitive" ), false ) );
        AutoCompSetDropRestOfWord( m_fileConfig->ReadBool( wxT( "/config/codecompletion/droprest" ), true ) );

        m_autoComplete = m_fileConfig->ReadBool( wxT( "/config/codecompletion/autocomplete" ), true );
        m_numberLetters = m_fileConfig->ReadInt( wxT( "/config/codecompletion/numberletters" ), 3 );
    }

    void Editor::LoadFoldSettings()
    {
        SetFoldFlags( m_fileConfig->ReadBool( wxT( "/config/fold/underline" ), true ) ? 16 : 0 );
        SetMarginType( MARGIN_FOLD, wxSCI_MARGIN_SYMBOL );
        SetMarginWidth( MARGIN_FOLD, m_fileConfig->ReadBool( wxT( "/config/fold/enable" ), true ) ? 16 : 0 );
        SetMarginMask( MARGIN_FOLD, wxSCI_MASK_FOLDERS );
        SetMarginSensitive( MARGIN_FOLD, true );

        SetProperty( wxT( "fold" ), m_fileConfig->ReadBool( wxT( "/config/fold/enable" ), true ) ? wxT( "1" ) : wxT( "0" ) );
        SetProperty( wxT( "fold.compact" ), wxT( "0" ) );
        SetProperty( wxT( "fold.comment" ), m_fileConfig->ReadBool( wxT( "/config/fold/foldcomment" ), true ) ? wxT( "1" ) : wxT( "0" ) );

        // muestra el simbolo + para desplegar codigo
        MarkerDefine( wxSCI_MARKNUM_FOLDER, m_fileConfig->ReadInt( wxT( "/config/fold/folder/symbol" ), wxSCI_MARK_BOXPLUS  ) );
        MarkerSetForeground( wxSCI_MARKNUM_FOLDER, m_fileConfig->ReadColour( wxT( "/config/fold/folder/foreground" ), wxT( "#FFFFFF" ) ) );
        MarkerSetBackground( wxSCI_MARKNUM_FOLDER, m_fileConfig->ReadColour( wxT( "/config/fold/folder/background" ), wxT( "#000000" ) ) );

        // muestra el simbolo - para plegar codigo
        MarkerDefine( wxSCI_MARKNUM_FOLDEROPEN, m_fileConfig->ReadInt( wxT( "/config/fold/folderopen/symbol" ), wxSCI_MARK_BOXMINUS ) );
        MarkerSetForeground( wxSCI_MARKNUM_FOLDEROPEN, m_fileConfig->ReadColour( wxT( "/config/fold/folderopen/foreground" ), wxT( "#FFFFFF" ) ) );
        MarkerSetBackground( wxSCI_MARKNUM_FOLDEROPEN, m_fileConfig->ReadColour( wxT( "/config/fold/folderopen/background" ), wxT( "#000000" ) ) );

        MarkerDefine( wxSCI_MARKNUM_FOLDERSUB, m_fileConfig->ReadInt( wxT( "/config/fold/foldersub/symbol" ), wxSCI_MARK_VLINE ) );
        MarkerSetForeground( wxSCI_MARKNUM_FOLDERSUB, m_fileConfig->ReadColour( wxT( "/config/fold/foldersub/foreground" ), wxT( "#000000" ) ) );
        MarkerSetBackground( wxSCI_MARKNUM_FOLDERSUB, m_fileConfig->ReadColour( wxT( "/config/fold/foldersub/background" ), wxT( "#000000" ) ) );

        MarkerDefine( wxSCI_MARKNUM_FOLDEREND, m_fileConfig->ReadInt( wxT( "/config/fold/folderend/symbol" ), wxSCI_MARK_BOXPLUSCONNECTED ) );
        MarkerSetForeground( wxSCI_MARKNUM_FOLDEREND, m_fileConfig->ReadColour( wxT( "/config/fold/folderend/foreground" ), wxT( "#FFFFFF" ) ) );
        MarkerSetBackground( wxSCI_MARKNUM_FOLDEREND, m_fileConfig->ReadColour( wxT( "/config/fold/folderend/background" ), wxT( "#000000" ) ) );

        MarkerDefine (wxSCI_MARKNUM_FOLDEROPENMID, m_fileConfig->ReadInt( wxT( "/config/fold/foldermid/symbol" ), wxSCI_MARK_BOXMINUSCONNECTED ) );
        MarkerSetForeground( wxSCI_MARKNUM_FOLDEROPENMID, m_fileConfig->ReadColour( wxT( "/config/fold/foldermid/foreground" ), wxT( "#FFFFFF" ) ) );
        MarkerSetBackground( wxSCI_MARKNUM_FOLDEROPENMID, m_fileConfig->ReadColour( wxT( "/config/fold/foldermid/background" ), wxT( "#000000" ) ) );

        MarkerDefine( wxSCI_MARKNUM_FOLDERMIDTAIL, m_fileConfig->ReadInt( wxT( "/config/fold/foldermidtail/symbol" ), wxSCI_MARK_TCORNER ) );
        MarkerSetForeground( wxSCI_MARKNUM_FOLDERMIDTAIL, m_fileConfig->ReadColour( wxT( "/config/fold/foldermidtail/foreground" ), wxT( "#000000" ) ) );
        MarkerSetBackground( wxSCI_MARKNUM_FOLDERMIDTAIL, m_fileConfig->ReadColour( wxT( "/config/fold/foldermidtail/background" ), wxT( "#000000" ) ) );

        MarkerDefine( wxSCI_MARKNUM_FOLDERTAIL, m_fileConfig->ReadInt( wxT( "/config/fold/foldertail/symbol" ), wxSCI_MARK_LCORNER ) );
        MarkerSetForeground( wxSCI_MARKNUM_FOLDERTAIL, m_fileConfig->ReadColour( wxT( "/config/fold/foldertail/foreground" ), wxT( "#000000" ) ) );
        MarkerSetBackground( wxSCI_MARKNUM_FOLDERTAIL, m_fileConfig->ReadColour( wxT( "/config/fold/foldertail/background" ), wxT( "#000000" ) ) );
    }









    void Editor::OnUpdateUI( wxScintillaEvent &evt )
    {
        HighlightBrace();
        HighlightOccurrences();

        evt.Skip();
    }

    void Editor::OnCharAddeed( wxScintillaEvent &evt )
    {
        if( m_lexer != NULL )
        {
            const int key( evt.GetKey() );
            const wxString strBrace = wxT( "({[]})" );
            if( m_fileConfig->ReadBool( wxT( "/config/general/indentbrace/autocomp" ), true ) && strBrace.Find( ( wxChar ) key ) != wxNOT_FOUND )
                AutoCompleteBrace( key );
            else
            {
                const int currentPos = GetCurrentPos();
                const int startPos = WordStartPosition( currentPos, true );

                if( m_autoComplete && currentPos - startPos >=  m_numberLetters )
                    Autocomplete();
            }
        }

        evt.Skip();
    }

    void Editor::OnMarginClick( wxScintillaEvent &evt )
    {
        if( evt.GetMargin() == MARGIN_FOLD )
        {
            int lineClick = LineFromPosition( evt.GetPosition() );
            int levelClick = GetFoldLevel( lineClick );

            if( ( levelClick & wxSCI_FOLDLEVELHEADERFLAG ) > 0 )
                ToggleFold( lineClick );
        }

        evt.Skip();
    }

    void Editor::OnKillFocus( wxFocusEvent &evt )
    {
        if( AutoCompActive() )
            AutoCompCancel();

        evt.Skip();
    }
}
